﻿using Activity.Comm;
using Activity.Data;
using Activity.Redis;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Web.Configuration;
using static Activity.Helper.CommHelper;

namespace Activity.API
{
    /// <summary>
    /// 处理抽奖类
    /// </summary>
    public class LotteryHandler
    {
        /// <summary>
        /// 结束时间
        /// </summary>
        static readonly DateTime endDate = new DateTime(2016, 11, 27, 23, 59, 59);

        /// <summary>
        /// 开始时间
        /// </summary>
        static readonly DateTime beginDate = new DateTime(2016, 11, 24, 0, 0, 0);

        /// <summary>
		/// 使用的Redis数据库索引
		/// </summary>
		public const int RedisDatabaseIndex = 4;

        /// <summary>
        /// 每天递减的奖品比例
        /// </summary>
        static readonly int[] LotteryRate = new int[] { 35, 25, 20, 20 };

        /// <summary>
        /// 测试
        /// </summary>
       static readonly string isDebug = WebConfigurationManager.AppSettings["isDebug"];

        /// <summary>
        /// 初始化奖池写入到redis
        /// </summary>
        /// <param name="isFirst"></param>
        public string InitPrizePool(bool isFirst = false)
        {
            if (!isFirst)
                return "已经初始化";
            var rc = new RedisClient(RedisDatabaseIndex);
            var pattern = "Suc:";
            var ListInitData = InitData();
            if (ListInitData != null)
            {
                foreach (var item in ListInitData)
                {
                    if (rc.KeyExists(item.ShopID)) rc.RemoveKey(item.ShopID);
                    //删除当天店铺总抽奖数
                    if (rc.KeyExists(pattern+item.ShopID)) rc.RemoveKey(pattern+item.ShopID);
                    rc.AddIntToList(item.ShopID, item.LotterArray);
                    Log.WriteLog("初始化店铺编号：" + item.ShopID + " 奖池成功");
                }
            }
            if (isDebug.ToLower() == "true")
            {
                TestHelper.testpos.Clear();
                TestHelper.InitTestData();
            }
            Log.WriteLog("初始化奖池时间:" + DateTime.Now);
            return "成功";
        }
        
        /// <summary>
        /// 抽奖
        /// </summary>
        /// <param name="openID"></param>
        /// <returns></returns>
        public Messages DrawPrize(string openID="")
        {
            try
            {
                if (string.IsNullOrWhiteSpace(openID)) return new Messages { IsSuc = false, Code = -1, Message = "无效的OPENID" };
                if (DateTime.Now < beginDate && isDebug.ToLower() == "false")
                {
                    return new Messages { IsSuc = false, Code = -1, Message = "亲，活动还没开始呢" };
                }
                if (DateTime.Now >= endDate && isDebug.ToLower() == "false")
                {
                    return new Messages { IsSuc = false, Code = 0, Message = "亲，活动已经结束了" };
                }
                var dc = new HKEntities();
                var rpt = new ActivityEntities();
                //通过openid将会员关联店铺编号

                var index = dc.KM_calShopVip(openID);
                var data = isDebug.ToLower() == "false" ? rpt.HD_V_PosList.Where(t => t.openid == openID) : TestHelper.testpos.Where(t => t.openid == openID);
                if (!data.Any()) return new Messages { IsSuc = false, Code = -1, Message = "亲、您的抽奖次数不够，快去购物吧。" };

                var rc = new RedisClient(RedisDatabaseIndex);
                var loop = 0;
                var query = (from a in dc.KM_V_CardBinding where a.OpenID == openID select a).FirstOrDefault();
                if (!rc.KeyExists(query.SaleShopID))
                {
                    Log.WriteLog("没找到对店铺数据错误：OPENID:" + openID + ",SHOPID:" + query.SaleShopID);
                    return new Messages { IsSuc = false, Code = -1, Message = "没找到对店铺数据" };
                }
                if (!rc.KeyExists("Suc:" + query.SaleShopID))
                    loop = 0;
                var random = new Random((int)DateTime.Now.Ticks);
                var values = 0;
                while (true)
                {
                    //当前各店奖池最大容量不超过200
                    var resultNum = random.Next(200) - 1;
                    values = rc.GetIntFromList(query.SaleShopID, resultNum);
                    var PoolLength = rc.GetListLength(query.SaleShopID);
                    if (values > 0)
                    {
                        //抽中奖后将中奖下票为resultNum修改为0
                        rc.SetIntToList(query.SaleShopID, resultNum, 0);
                        loop = rc.GetInt("Suc:" + query.SaleShopID);
                        loop = loop + 1;
                        rc.SetInt("Suc:" + query.SaleShopID, loop);
                        var _posCode = data.FirstOrDefault()?.billno;

                        if (isDebug.ToLower() == "true") TestHelper.testpos.Remove(TestHelper.testpos.FirstOrDefault(t => t.openid==openID && t.billno==_posCode));
                        #region 写入日志

                        var addLog = new HD_WinningLog
                        {
                            ShopID = query.SaleShopID,
                            CreateTime = DateTime.Now,
                            OpenID = openID,
                            PosCode = _posCode,
                            ProdType = values
                        };
                        rpt.HD_WinningLog.Add(addLog);
                        try
                        {
                            rpt.SaveChanges();
                            if (values == 7)
                                CalculateIntegral(query.CardID, query.CardCode, query.SaleShopID);
                            return new Messages { IsSuc = true, Code = 1, Message = values.ToString() };
                        }
                        catch (Exception ex)
                        {
                            Log.Error(ex);
                            return new Messages { IsSuc = false, Code = -1, Message = ex.Message };
                        }
                        #endregion
                    }
                    else
                    {
                        #region 超出中奖数则是返回积分奖励
                        if (loop >= PoolLength)
                        {
                            values = 7;
                            #region 写入日志
                            var addLog = new HD_WinningLog
                            {
                                ShopID = query.SaleShopID,
                                CreateTime = DateTime.Now,
                                OpenID = openID,
                                PosCode = data?.FirstOrDefault().billno,
                                ProdType = values
                            };
                            rpt.HD_WinningLog.Add(addLog);
                            try
                            {
                                rpt.SaveChanges();
                                CalculateIntegral(query.CardID, query.CardCode, query.SaleShopID);
                                return new Messages { IsSuc = true, Code = 1, Message = values.ToString() };
                            }
                            catch (Exception ex)
                            {
                                Log.Error(ex);
                                return new Messages { IsSuc = false, Code = -1, Message = ex.Message };
                            }
                            #endregion
                        }
                        #endregion
                    }
                    continue;
                }
            }catch(Exception ex)
            {
                Log.Error("抽奖异常:"+ex);
                return new Messages { IsSuc = false, Code = -1, Message = "抽奖异常" };
            }
        }

        /// <summary>
        /// 会员抽中积分实时更新到账户
        /// </summary>
       public void CalculateIntegral(string CardID,string CardCode,string ShopID)
        {
            if (isDebug.ToLower() == "true") return;
            var dc = new HKEntities();
            var userInfo = dc.CRM_Bas_CardInfo.FirstOrDefault(t=>t.CardID==CardID);
            if(userInfo !=null)
            {
                userInfo.RemainIntegral += 50;
                userInfo.TotalIntegral += 50;
            }
            var billNo = "AI" + CardID + DateTime.Now.Ticks;
            var master = new CRM_Oper_AdjIntegralMaster
            {
                AdjIntegralType = "7",
                CompanyID = "KM",
                BillDate = DateTime.Now,
                BillNo = billNo,
                ShopID = ShopID,
                BillStatus = 4,
                Finished = false,
                ModifyDTM = DateTime.Now,
                Remark = "2016感恩节抽奖",
                BillTypeID= "Crm_Oper_AdjInt",
                IsPosBuild=false,
                Checker= "KM00000005",
                Operator= "KM00000005"
            };
            dc.CRM_Oper_AdjIntegralMaster.Add(master);
            //var qt = dc.CRM_Oper_AdjIntegralDetail.Max(t => t.Sequence);
            //var seq = (Convert.ToInt32(qt)+1).ToString();
            var seq = DateTime.Now.Ticks.ToString();
            var detail = new CRM_Oper_AdjIntegralDetail
            {
                BillNo = master.BillNo,
                CompanyID = master.CompanyID,
                Sequence = seq,
                CardTypeID = "00000000000036",
                CardCode = CardCode,
                AdjustIntegral=50,
                NewIntegral = 50,
                Remark = "2016感恩节抽奖中积分",
                ClearIntegralFlag = false,
                
            };
            dc.CRM_Oper_AdjIntegralDetail.Add(detail);
            try
            {
                dc.SaveChanges();
                Log.WriteLog("用户编号 " + CardID + " 增加50积分");
            }
            catch(Exception ex)
            {
                Log.WriteLog("用户编号 " + CardID + " 增加出错:"+ex);
            }
        }

        /// <summary>
        /// 初始化奖池
        /// </summary>
        /// <returns></returns>
        List<InitProductData> InitData()
        {
            var dc = new ActivityEntities();
            var query = dc.HD_Product;
            if (query != null)
            {
                int DrawDay = 0;
                var list = new List<InitProductData>();
                var _rate = Rate(ref DrawDay);
                try
                {
                    foreach (var item in query.ToList())
                    {
                        var data = new InitProductData();
                        #region 计算每天每类奖品的量
                        var fingerRing = 0d;
                        var led = 0d;
                        var sportRing = 0d;
                        var parts10 = 0d;
                        var pillowBlanket = 0d;
                        var heatAir = 0d;
                        var integral = 0d;
                        if (DrawDay != 27)
                        {
                            fingerRing = Math.Round((int)item.FingerRing * _rate, 0);
                            led = Math.Round((int)item.LED * _rate, 0);
                            sportRing = Math.Round((int)item.SportRing * _rate, 0);
                            parts10 = Math.Round((int)item.Parts10 * _rate, 0);
                            pillowBlanket = Math.Round((int)item.PillowBlanket * _rate, 0);
                            heatAir = Math.Round((int)item.HeatAir * _rate, 0);
                            integral = Math.Round((int)item.Integral * _rate, 0);
                        }
                        else
                        {
                            var qs = dc.V_WinningGroup.FirstOrDefault(t => t.ShopID == item.ShopID);
                            fingerRing = (double)qs.FingerRing;
                            led = (double)qs.LED;
                            sportRing = (double)qs.SportRing;
                            parts10 = (double)qs.Parts10;
                            pillowBlanket = (double)qs.PillowBlanket;
                            heatAir = (double)qs.HeatAir;
                            integral = (double)qs.Integral;
                        }
                        #endregion
                        int l = 0;
                        var TotalLength = fingerRing + led + sportRing + parts10 + pillowBlanket + heatAir + integral;
                        int[] shopPool = new int[(int)TotalLength];
                        GeneratePool((int)fingerRing, LotteryType.FingerRing, ref shopPool, ref l);
                        GeneratePool((int)led, LotteryType.Led, ref shopPool, ref l);
                        GeneratePool((int)sportRing, LotteryType.SportRing, ref shopPool, ref l);
                        GeneratePool((int)parts10, LotteryType.Parts10, ref shopPool, ref l);
                        GeneratePool((int)pillowBlanket, LotteryType.PillowBlanket, ref shopPool, ref l);
                        GeneratePool((int)heatAir, LotteryType.HeatAir, ref shopPool, ref l);
                        GeneratePool((int)integral, LotteryType.Integral, ref shopPool, ref l);

                        //输出数组类型
                        ArrayItem<int> disrupter = new ArrayItem<int>(shopPool);
                        //输出一个打乱后数组
                        data.ShopID = item.ShopID;
                        data.LotterArray = disrupter.GetDisruptedItems();
                        list.Add(data);
                    }
                    return list;
                }catch(Exception ex)
                {
                    Log.Error(ex);
                }
            }
            return null;
        }

        /// <summary>
        /// 生成奖池
        /// </summary>
        /// <returns></returns>
        void GeneratePool(int len,LotteryType type, ref int[] shopPool,ref int l)
        {
            for (int i = 0; i < len; i++)
            {
                if(type==LotteryType.FingerRing)
                   shopPool[l] = (int)LotteryType.FingerRing;
                if (type == LotteryType.Led)
                    shopPool[l] = (int)LotteryType.Led;
                if (type == LotteryType.SportRing)
                    shopPool[l] = (int)LotteryType.SportRing;
                if (type == LotteryType.Parts10)
                    shopPool[l] = (int)LotteryType.Parts10;
                if (type == LotteryType.PillowBlanket)
                    shopPool[l] = (int)LotteryType.PillowBlanket;
                if (type == LotteryType.HeatAir)
                    shopPool[l] = (int)LotteryType.HeatAir;
                if (type == LotteryType.Integral)
                    shopPool[l] = (int)LotteryType.Integral;
                l++;
            }
        }

        /// <summary>
        /// 返回奖品分配比例
        /// </summary>
        /// <returns></returns>
        private double Rate(ref int days)
        {
            if (DateTime.Now.Day == 27)
            {
                //返回27，侧用店铺总奖品数减已抽奖数,预防最后一天真实的奖品数
                days = 27;
                return 27;
            }
            if (DateTime.Now.Day == 25)
            {
                days = 25;
                return LotteryRate[1] * 0.01;
            }
            if (DateTime.Now.Day == 26)
            {
                days = 26;
                return LotteryRate[2] * 0.01;
            }
            days = 24;
            return LotteryRate[0] * 0.01;
        }


        /// <summary>
        /// 返回个人中奖列表
        /// </summary>
        /// <param name="openID"></param>
        /// <returns></returns>
        public List<LotteryResult> LotteryList(string openID)
        {
            var dc = new ActivityEntities();
            var query = dc.HD_WinningLog.Where(t=>t.OpenID==openID);
            if (!query.Any()) return new List<LotteryResult>();
            var result = query.Select(o => new LotteryResult
            {
                ProductType = (int)o.ProdType,
                CreateDate = (DateTime)o.CreateTime
            }).ToList();
            return result;
        }
    }

    public class InitProductData
    {
        public string ShopID { get; set; }

        public int[] LotterArray { get; set; }
    }

    /// <summary>
    /// 中奖列表
    /// </summary>
    public class LotteryResult
    {
        public int ProductType { get; set; }
        public DateTime CreateDate { get; set; }
    }

    /// <summary>
    /// 返回结果
    /// </summary>
    public class Messages
    {
        public bool IsSuc { get; set; }
        public string Message { get; set; }
        public int Code { get; set; }
    }

    /// <summary>
    /// 奖品类型
    /// </summary>
    public enum LotteryType {
        FingerRing = 1,
        Led = 2,
        SportRing = 3,
        Parts10 = 4,
        PillowBlanket = 5,
        HeatAir = 6,
        Integral = 7
    }
}
